using System;
using System.Data.SqlClient;
using System.Text.RegularExpressions;

using ObjectRelationalMapping.Helper;
using ObjectRelationalMapping.Model;

namespace ObjectRelationalMapping
{
    internal static partial class Mapper
    {
        internal static void Generate ( )
        {
            QueryTablesFromDatabase ();
            QueryColumnsFromDatabase ();
        }

        private static void QueryColumnsFromDatabase ( )
        {
            if ( Common.EntityCollection.Count > 0 )
            {
                Console.Write ( "Querying the database for columns..." );
                int numberOfColumns = 0;

                foreach ( Entity entity in Common.EntityCollection )
                {
                    string temporaryQueryColumnsCommand =
                        Regex.Replace (
                            Common.QueryColumnsCommand,
                            Common.Constants.UserDefinedTableName,
                            entity.Name );
                    using ( SqlDataReader dataReader =
                        Sql.ExecuteReader ( temporaryQueryColumnsCommand ) )
                    {
                        while ( dataReader.Read () )
                        {
                            bool isNullable =
                                ( dataReader.IsDBNull ( 3 )
                                    ? false : 
                                    ( dataReader.GetString ( 3 ) == "YES" 
                                        ? true : false ) );
                            bool isPrimaryKey =
                                ( dataReader.IsDBNull ( 4 )
                                    ? false : dataReader.GetBoolean ( 4 ) );
                            string name =
                                ( dataReader.IsDBNull ( 0 )
                                    ? string.Empty : dataReader.GetString ( 0 ) );
                            int length =
                                ( dataReader.IsDBNull ( 1 )
                                    ? 0 : dataReader.GetInt32 ( 1 ) );
                            string type =
                                ( dataReader.IsDBNull ( 2 )
                                    ? string.Empty : dataReader.GetString ( 2 ) );

                            Property<Metaclass> metaclassProperty =
                                new Property<Metaclass> ();
                            metaclassProperty.IsNullable = isNullable;
                            metaclassProperty.IsPrimaryKey = isPrimaryKey;
                            metaclassProperty.Name = name;
                            metaclassProperty.Type = type;
                            entity.Metaclass.Properties.Add (
                                metaclassProperty );

                            Property<Metadata> metadataProperty =
                                new Property<Metadata> ();
                            metadataProperty.IsNullable = isNullable;
                            metadataProperty.IsPrimaryKey = isPrimaryKey;
                            metadataProperty.Length = length;
                            metadataProperty.Name = name;
                            metadataProperty.Type = type;
                            entity.Metadata.Properties.Add (
                                metadataProperty );

                            ++numberOfColumns;
                        }
                    }
                }

                Console.WriteLine (
                    "and {0} columns were found.", numberOfColumns );
            }

            Console.WriteLine ( string.Empty );
        }

        private static void QueryTablesFromDatabase ( )
        {
            Console.Write ( "Querying the database for tables..." );
            int numberOfUserTables = 0;

            using (
                SqlDataReader dataReader =
                    Sql.ExecuteReader (
                        Common.QueryTablesCommand ) )
            {
                while ( dataReader.Read () )
                {
                    Entity entity = new Entity ();
                    entity.Name = dataReader.GetString ( 0 );
                    if ( !Common.ExcludedTableCollection.Contains ( entity.Name ) )
                    {
                        Common.EntityCollection.Add ( entity );
                        ++numberOfUserTables;
                    }
                }
            }

            Console.WriteLine (
                "and {0} tables were found.", numberOfUserTables );
        }
    }
}